#include "tos_k.h"
#include "tos_hal.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_lpuart.h"
typedef struct __UART_HandleTypeDef
{
	LPUART_Type *channel;
} UART_HandleTypeDef;

typedef enum {
  HAL_ERROR = -1,
  HAL_OK = 0x00U,

  HAL_BUSY = 0x02U,
  HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;

UART_HandleTypeDef huart0;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;


__API__ int tos_hal_uart_init(hal_uart_t *uart, hal_uart_port_t port)
{
    lpuart_config_t config;
    if (!uart) {
        return -1;
    }

    if (port == HAL_UART_PORT_0) {
        uart->private_uart = &huart0;
        huart0.channel = LPUART4;
        LPUART_GetDefaultConfig(&config);
        config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
        config.enableTx     = true;
        config.enableRx     = true;

        LPUART_Init(LPUART4, &config, BOARD_DebugConsoleSrcFreq());

        /* Enable RX interrupt. */
        LPUART_EnableInterrupts(LPUART4, kLPUART_RxDataRegFullInterruptEnable);
        EnableIRQ(LPUART4_IRQn);

    } else if (port == HAL_UART_PORT_1) {


        uart->private_uart = &huart1;
        huart1.channel = LPUART1;
        LPUART_GetDefaultConfig(&config);
        config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
        config.enableTx     = true;
        config.enableRx     = true;

        LPUART_Init(LPUART1, &config, BOARD_DebugConsoleSrcFreq());

        /* Enable RX interrupt. */
        LPUART_EnableInterrupts(LPUART1, kLPUART_RxDataRegFullInterruptEnable);
        EnableIRQ(LPUART1_IRQn);

    } else if (port == HAL_UART_PORT_2) {

        uart->private_uart = &huart2;
        huart2.channel = LPUART2;
        LPUART_GetDefaultConfig(&config);
        config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
        config.enableTx     = true;
        config.enableRx     = true;

        LPUART_Init(LPUART2, &config, BOARD_DebugConsoleSrcFreq());

        /* Enable RX interrupt. */
        LPUART_EnableInterrupts(LPUART2, kLPUART_RxDataRegFullInterruptEnable);
        EnableIRQ(LPUART2_IRQn);
    }
    return 0;
}

__API__ int tos_hal_uart_write(hal_uart_t *uart, const uint8_t *buf, size_t size, uint32_t timeout)
{
    HAL_StatusTypeDef hal_status;
    UART_HandleTypeDef *uart_handle;

    if (!uart || !buf) {
        return -1;
    }

    if (!uart->private_uart) {
        return -1;
    }

    uart_handle = (UART_HandleTypeDef *)uart->private_uart;

    hal_status = LPUART_WriteBlocking(uart_handle->channel, (uint8_t *)buf, size);
    if (hal_status != kStatus_Success) {
        return -1;
    }
    return 0;
}


__API__ int tos_hal_uart_read(hal_uart_t *uart, const uint8_t *buf, size_t size, uint32_t timeout)
{
    return 0;
}

__API__ int tos_hal_uart_deinit(hal_uart_t *uart)
{
    HAL_StatusTypeDef hal_status;
    UART_HandleTypeDef *uart_handle;

    if (!uart) {
        return -1;
    }

    if (!uart->private_uart) {
        return -1;
    }

    uart_handle = (UART_HandleTypeDef *)uart->private_uart;

    LPUART_Deinit(uart_handle->channel);


    return 0;
}

